using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;

using FreeFlow.Client;
using FreeFlow.Client.Events;

namespace FreeFlow.WinFormsControls
{
	/// <summary>
	/// Control to display a folder in an action.
	/// </summary>
	public class ActionPageControl : ConnectableControl
	{
    private System.Windows.Forms.Button submitButton;
    private System.Windows.Forms.Button cancelButton;
		/// <summary> 
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;
    private System.Windows.Forms.Panel panel2;
    private FreeFlow.WinFormsControls.FormControl formControl;
    private System.Windows.Forms.Panel buttonPanel;

    private ActionPage actionPage;
    /// <summary>
    /// Creates a new <see cref="ActionPageControl"/> instance.
    /// </summary>
		public ActionPageControl()
		{
			// This call is required by the Windows.Forms Form Designer.
			InitializeComponent();

			actionPage = new ActionPage();
		}

		/// <summary> 
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Component Designer generated code
		/// <summary> 
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
      this.buttonPanel = new System.Windows.Forms.Panel();
      this.cancelButton = new System.Windows.Forms.Button();
      this.submitButton = new System.Windows.Forms.Button();
      this.panel2 = new System.Windows.Forms.Panel();
      this.formControl = new FreeFlow.WinFormsControls.FormControl();
      this.buttonPanel.SuspendLayout();
      this.panel2.SuspendLayout();
      this.SuspendLayout();
      // 
      // buttonPanel
      // 
      this.buttonPanel.Controls.Add(this.cancelButton);
      this.buttonPanel.Controls.Add(this.submitButton);
      this.buttonPanel.Dock = System.Windows.Forms.DockStyle.Bottom;
      this.buttonPanel.Location = new System.Drawing.Point(0, 264);
      this.buttonPanel.Name = "buttonPanel";
      this.buttonPanel.Size = new System.Drawing.Size(544, 40);
      this.buttonPanel.TabIndex = 1;
      // 
      // cancelButton
      // 
      this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
      this.cancelButton.FlatStyle = System.Windows.Forms.FlatStyle.System;
      this.cancelButton.Location = new System.Drawing.Point(464, 8);
      this.cancelButton.Name = "cancelButton";
      this.cancelButton.Size = new System.Drawing.Size(75, 23);
      this.cancelButton.TabIndex = 1;
      this.cancelButton.Text = "Cancel";
      this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
      // 
      // submitButton
      // 
      this.submitButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
      this.submitButton.FlatStyle = System.Windows.Forms.FlatStyle.System;
      this.submitButton.Location = new System.Drawing.Point(384, 8);
      this.submitButton.Name = "submitButton";
      this.submitButton.Size = new System.Drawing.Size(75, 23);
      this.submitButton.TabIndex = 0;
      this.submitButton.Text = "Submit";
      this.submitButton.Click += new System.EventHandler(this.submitButton_Click);
      // 
      // panel2
      // 
      this.panel2.Controls.Add(this.formControl);
      this.panel2.Dock = System.Windows.Forms.DockStyle.Fill;
      this.panel2.Location = new System.Drawing.Point(0, 0);
      this.panel2.Name = "panel2";
      this.panel2.Size = new System.Drawing.Size(544, 264);
      this.panel2.TabIndex = 2;
      // 
      // formControl
      // 
      this.formControl.AutoScroll = true;
      this.formControl.Dock = System.Windows.Forms.DockStyle.Fill;
      this.formControl.Location = new System.Drawing.Point(0, 0);
      this.formControl.Name = "formControl";
      this.formControl.Size = new System.Drawing.Size(544, 264);
      this.formControl.TabIndex = 1;
      this.formControl.OpenBlankForm += new System.EventHandler<FreeFlow.Client.Events.OpenBlankFormEventArgs>(this.formControl_OpenBlankForm);
      this.formControl.SubmitForm += new System.EventHandler(this.formControl_SubmitForm);
      this.formControl.CancelForm += new System.EventHandler(this.formControl_CancelForm);
      this.formControl.RefillForm += new System.EventHandler<FreeFlow.Client.Events.RefillFormEventArgs>(this.formControl_RefillForm);
      this.formControl.OpenFolder += new System.EventHandler<FreeFlow.Client.Events.OpenFolderEventArgs>(this.formControl_OpenFolder);
      // 
      // ActionPageControl
      // 
      this.Controls.Add(this.panel2);
      this.Controls.Add(this.buttonPanel);
      this.Name = "ActionPageControl";
      this.Size = new System.Drawing.Size(544, 304);
      this.buttonPanel.ResumeLayout(false);
      this.panel2.ResumeLayout(false);
      this.ResumeLayout(false);

    }
		#endregion
    #region properties
    /// <summary>
    /// Gets or sets the engine connection.
    /// </summary>
    [Description("The connection used to connect to the engine")]
    [Category(Constants.FreeFlowCategory)]
    public override Connection Connection
    {
      set 
      { 
        base.Connection = value; 
        actionPage.Connection = value;
      }
    }

    /// <summary>
    /// Gets the preferred height of the control.
    /// </summary>
    public int PreferredHeight
    {
      get
      {
        if (actionPage.Form != null)
          return actionPage.Form.Height + buttonPanel.Height;
        
        return Height;
      }
    }

    /// <summary>
    /// Gets the preferred width of the control.
    /// </summary>
    public int PreferredWidth
    {
      get
      {
        if (actionPage.Form != null)
          return actionPage.Form.Width;

        return Width; 
      }
    }

    /// <summary>
    /// Gets the preferred size of the control.
    /// </summary>
    public Size PreferredControlSize
    {
      get
      {
        return new Size(PreferredWidth, PreferredHeight);
      }
    }

    /// <summary>
    /// Gets the name of the folder.
    /// </summary>
    public string FolderName
    {
      get
      {
        return actionPage.FolderName;
      }
    }

    #endregion
    #region submit
    /// <summary>
    /// Event triggered when the user has submitted the action.
    /// </summary>
    [Category(Constants.FreeFlowCategory)]
    public event EventHandler SubmitActionForm;

    private void submitButton_Click(object sender, System.EventArgs e)
    {
      Submit();
    }

    /// <summary>
    /// Submits the action form.
    /// </summary>
    public void Submit()
    {
      formControl.UpdateFormValues(actionPage.Form);
      if (formControl.ValidateFields())
      {
        string chainedAction;
        string reopenFolderId;
        actionPage.Submit(out chainedAction, out reopenFolderId);
        
        // re-open folder
        if (reopenFolderId != null)
        {
          OnOpenFolder(new OpenFolderEventArgs(reopenFolderId));
        }

        // chained action
        if (chainedAction == null)
        {
          OnSubmitActionForm();
        }
        else
        {
          StartAction(actionPage.FolderId, chainedAction);
        }
      }
    }

    private void OnSubmitActionForm()
    {
      if (SubmitActionForm != null)
        SubmitActionForm(this, EventArgs.Empty);
    }

    private void formControl_SubmitForm(object sender, System.EventArgs e)
    {
      Submit();
    }
    #endregion
    #region cancel
    /// <summary>
    /// Event triggered when the user has cancelled the action.
    /// </summary>
    [Category(Constants.FreeFlowCategory)]
    public event EventHandler CancelActionForm;

    private void cancelButton_Click(object sender, System.EventArgs e)
    {
      Cancel();
    }

    /// <summary>
    /// Cancels the action form.
    /// </summary>
    public void Cancel()
    {
      actionPage.Cancel();
      if (CancelActionForm != null)
        CancelActionForm(this, EventArgs.Empty);
    }

    private void formControl_CancelForm(object sender, System.EventArgs e)
    {
      Cancel();
    }
    #endregion

    /// <summary>
    /// Populates the control for the specified blank form.
    /// </summary>
    /// <param name="processName">Name of the process.</param>
    /// <param name="actionName">Name of the action.</param>
    public void StartBlankForm(string processName, string actionName)
    {
      // populate
      actionPage.StartBlankForm(processName, actionName);
      HandleForm();
    }

    /// <summary>
    /// Populates the control for the specified blank form. If the process contains multiple blank forms, 
    /// the one whose eAction.eActionID equals 1 will be started.
    /// </summary>
    /// <param name="processName">Name of the process.</param>
    public void StartBlankForm(string processName)
    {
      StartBlankForm(processName, string.Empty);
    }

    /// <summary>
    /// Populates the control for the specified action.
    /// </summary>
    /// <param name="folderId">Folder id.</param>
    /// <param name="actionName">Name of the action.</param>
    public void StartAction(string folderId, string actionName)
    {
      actionPage.StartAction(folderId, actionName);
      HandleForm();
    }

    private void HandleForm()
    {
      if (actionPage.Form == null)
      {
        if (actionPage.Confirm)
        {
          Label label = new Label();
          label.TextAlign = ContentAlignment.MiddleCenter;
          label.Text = "Are you sure?";
          label.Dock = DockStyle.Fill;
          formControl.Controls.Add(label);
        }
        else
          OnSubmitActionForm();
      }
      else
        formControl.Populate(actionPage.Form);
    }

    private void formControl_RefillForm(object sender, FreeFlow.Client.Events.RefillFormEventArgs e)
    {
      formControl.UpdateFormValues(actionPage.Form);
      actionPage.Refill(e.UpdatedField);
      // repopulate fields
      formControl.PopulateControls(actionPage.Form);
    }

    private void formControl_OpenBlankForm(object sender, FreeFlow.Client.Events.OpenBlankFormEventArgs e)
    {
      if (OpenBlankForm != null)
        OpenBlankForm(this, e);
    }

    /// <summary>
    /// Event triggered when the user presses a button that opens a blank form.
    /// </summary>
    [Category(Constants.FreeFlowCategory)]
    public event EventHandler<OpenBlankFormEventArgs> OpenBlankForm;

    private void formControl_OpenFolder(object sender, FreeFlow.Client.Events.OpenFolderEventArgs e)
    {
      OnOpenFolder(e);
    }

    private void OnOpenFolder(OpenFolderEventArgs e)
    {
      if (OpenFolder != null)
        OpenFolder(this, e);
    }

    /// <summary>
    /// Event triggered when the user presses a button that opens a folder.
    /// </summary>
    [Category(Constants.FreeFlowCategory)]
    public event EventHandler<OpenFolderEventArgs> OpenFolder;
	}
}
